package com.authine.cloudpivot.controller;


import com.authine.cloudpivot.engine.api.model.BaseModel;
import com.authine.cloudpivot.engine.api.model.organization.*;
import com.authine.cloudpivot.engine.api.model.permission.DepartmentScopeModel;
import com.authine.cloudpivot.engine.api.model.runtime.SelectionValue;
import com.authine.cloudpivot.engine.api.model.system.AdminModel;
import com.authine.cloudpivot.engine.api.model.system.RelatedCorpSettingModel;
import com.authine.cloudpivot.engine.enums.type.OrgType;
import com.authine.cloudpivot.engine.enums.type.UnitType;
import com.authine.cloudpivot.web.api.controller.base.PermissionController;
import com.authine.cloudpivot.web.api.controller.orgnization.SelectionHelper;
import com.authine.cloudpivot.web.api.controller.orgnization.SelectionHelperExt;
import com.authine.cloudpivot.web.api.controller.orgnization.UserController;
import com.authine.cloudpivot.web.api.handler.CustomizedOrigin;
import com.authine.cloudpivot.web.api.task.RunTimeThreadTask;
import com.authine.cloudpivot.web.api.util.ReflectUtil;
import com.authine.cloudpivot.web.api.view.ResponseResult;
import com.authine.cloudpivot.web.api.view.organization.DepartmentUserTreeVO;
import com.authine.cloudpivot.web.api.view.organization.DepartmentVO;
import com.authine.cloudpivot.web.api.view.organization.UserSelectionVO;
import com.google.common.collect.Lists;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.StopWatch;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.PostConstruct;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
import java.util.stream.Collectors;

@Api(
        tags = {"组织机构::用户搜索扩展"}
)
@RestController
@RequestMapping({"/api/organization/user"})
@Validated
@CustomizedOrigin(
        level = 1
)
public class ExUserController extends PermissionController {


    private static final Logger log = LoggerFactory.getLogger(UserController.class);
    @Autowired
    private RunTimeThreadTask springThreadTask;
    @Autowired
    private SelectionHelper selectionHelper;
    @Autowired
    private SelectionHelperExt selectionHelperExt;
    @Value("${cloudpivot.bizobject.userQuerySize:20}")
    private Integer organizationUserQuerySize;
    @Value("${cloudpivot.organization.defaultPwd:Ln54z(XOZ+*t}")
    private String defaultPwd;
    @Value("${cloudpivot.organization.login.getLastLoginTime:false}")
    private boolean genLastLoginTime;
    private int cacheSize;
    public Set<String> idSetCache = new HashSet();
    public Map<String, String> departmentMapCache;


    @Value("${cloudpivot.cache.deptMapSize:2000}")
    public void setCacheSize(int size) {
        this.cacheSize = size;
    }

    @PostConstruct
    private void init() {
        this.departmentMapCache = new LinkedHashMap((int)Math.ceil((double)this.cacheSize / 0.75D) + 1, 0.75F, true) {
            protected synchronized boolean removeEldestEntry(Map.Entry eldest) {
                if (this.size() > cacheSize) {
                    idSetCache.remove(eldest.getKey());
                    return true;
                } else {
                    return false;
                }
            }
        };
    }


    @GetMapping({"/tree/search"})
    @ApiOperation(
            value = "选人控件根据名称搜索人或部门",
            notes = "选人控件根据名称搜索人或部门"
    )
    @ApiImplicitParam(
            name = "name",
            value = "搜索名称",
            required = true,
            dataType = "String"
    )
    @ApiImplicitParams({@ApiImplicitParam(
            name = "name",
            value = "搜索名称",
            required = true,
            dataType = "String"
    ), @ApiImplicitParam(
            name = "deptIds",
            value = "部门编码 “,”分割",
            dataType = "String"
    ), @ApiImplicitParam(
            name = "roleIds",
            value = "角色编码 “,”分割",
            dataType = "String"
    ), @ApiImplicitParam(
            name = "corpId",
            value = "关联组织编码 “,”分割",
            dataType = "String"
    ), @ApiImplicitParam(
            name = "sourceType",
            value = "来源类型，admin-后台，portal-门户",
            dataType = "String",
            paramType = "query"
    ), @ApiImplicitParam(
            name = "workflowInstanceId",
            value = "流程实例id",
            dataType = "String",
            paramType = "query"
    ), @ApiImplicitParam(
            name = "activityCode",
            value = "节点编码",
            dataType = "String",
            paramType = "query"
    ), @ApiImplicitParam(
            name = "selectUserIds",
            value = "选人控件中选中的用户id集合，逗号隔开，用来过滤其所在部门和兼职部门及其下子部门，和当前查询的应用管理员权限取交集",
            dataType = "String",
            paramType = "query"
    ), @ApiImplicitParam(
            name = "filterType",
            value = "过滤方式 admin admin_corp-应用管理员  main-只显示主部门  self-只显示自维护组织“,”分割",
            required = false,
            dataType = "String"
    ), @ApiImplicitParam(
            name = "formRootDeptIds",
            value = "表单根部门id",
            dataType = "String",
            paramType = "query"
    ), @ApiImplicitParam(
            name = "queryType",
            value = "查询类型",
            dataType = "String"
    )})
    public ResponseResult<DepartmentUserTreeVO> search(String name, String deptIds, String roleIds, @RequestParam(required = false) String filterType, @RequestParam(required = false) String corpId, String sourceType, String workflowInstanceId, String activityCode, String selectUserIds, @RequestParam(required = false) String formRootDeptIds, @RequestParam(required = false) String queryType) {
        StopWatch watch = new StopWatch();
        watch.start();
        UserModel currentUser = this.getOrganizationFacade().getUser(this.getUserId());
        List<RelatedCorpSettingModel> allRelatedCorpSettingModel = this.getRelatedCorpSettingFacade().listAll();
        Map<String, RelatedCorpSettingModel> corpMap = (Map)allRelatedCorpSettingModel.stream().collect(Collectors.toMap(RelatedCorpSettingModel::getCorpId, Function.identity()));
        String excludedeptid = null;
        RelatedCorpSettingModel relatedCorpSettingModel;
        if (StringUtils.isNotEmpty(corpId) && "MAIN_ORG".equals(corpId)) {
            relatedCorpSettingModel = (RelatedCorpSettingModel)corpMap.values().stream().filter((item) -> {
                return OrgType.MAIN == item.getOrgType();
            }).findFirst().get();
            corpId = relatedCorpSettingModel.getCorpId();
        } else if (StringUtils.isNotEmpty(corpId) && corpId.startsWith("userid")) {
            String assignUserId = corpId.replace("userid-", "");
            UserModel u = this.getOrganizationFacade().getUser(assignUserId);
            corpId = u.getCorpId();
        } else if (StringUtils.isNotEmpty(corpId) && corpId.contains("excludedeptid")) {
            String[] excludedeptidArr = corpId.split("@@excludedeptid-");
            corpId = excludedeptidArr[0];
            excludedeptid = excludedeptidArr[1];
        }

        relatedCorpSettingModel = null;
        if (StringUtils.isNotBlank(sourceType)) {
            relatedCorpSettingModel = (RelatedCorpSettingModel)corpMap.get(currentUser.getCorpId());
        }

        Set<String> permUserIdSet = new HashSet();
        SelectionHelper.SelectionFilter filterInfo = this.selectionHelper.relatedSelection(filterType, sourceType, corpId, this.getUserId());
        Set<String> filterCorpIdSet = filterInfo.getCorpIds();
        Set<String> managePermChildDepartment;
        List<DepartmentModel> departmentList;
        if (filterInfo.isNeedFilterAppAdmin()) {
            if (StringUtils.isNotBlank(selectUserIds)) {
                managePermChildDepartment = this.getLoginUserDeptPermAndSelectUsersMixed(this.getManagePermChildDepartmentId(this.getUserId()), selectUserIds);
            } else {
                Set<String> managePermChildDepartments = this.getManagePermChildDepartmentId(this.getUserId());
                AdminModel appAdminByUser = this.getAppAdminByUserId(this.getUserId());
                List<DepartmentScopeModel> departments = appAdminByUser.getDepartments();
                Set<String> corpIds = new HashSet();
                if (!CollectionUtils.isEmpty(departments)) {
                    Set<String> departmentIds = (Set)departments.stream().filter((departmentScopeModel) -> {
                        return Objects.nonNull(departmentScopeModel.getUnitId());
                    }).map(DepartmentScopeModel::getUnitId).collect(Collectors.toSet());
                    departmentList = this.getOrganizationFacade().getDepartmentsByDeptIds(new ArrayList(departmentIds));
                    if (CollectionUtils.isNotEmpty(departmentList)) {
                        corpIds.addAll((Collection)departmentList.stream().map(DepartmentModel::getCorpId).collect(Collectors.toSet()));
                    }
                }

                departmentList = this.getOrganizationFacade().getDepartmentsByDeptIds(new ArrayList(managePermChildDepartments));
                managePermChildDepartment = departmentList.stream().filter((item) -> {
                    return corpIds.contains(item.getCorpId());
                }).map(BaseModel::getId).collect(Collectors.toSet());
            }

            if (CollectionUtils.isNotEmpty((Collection)managePermChildDepartment)) {
                permUserIdSet = this.getOrganizationFacade().getUserIdsByDepartmentIds(new ArrayList((Collection)managePermChildDepartment));
            }
        } else {
            permUserIdSet = new HashSet();
            managePermChildDepartment = new HashSet();
        }

        boolean finalNeedFilterCorp = filterInfo.isNeedFilterCorp();
        Set<String> displayDep = new HashSet();
        Set<String> depUserIds = new HashSet();
        if (StringUtils.isNotBlank(deptIds)) {
            departmentList = this.getOrganizationFacade().getDepartmentsChildList(Arrays.asList(deptIds.split(",")));
            displayDep = (Set)departmentList.stream().map(BaseModel::getId).collect(Collectors.toSet());
            depUserIds = this.getOrganizationFacade().getUserIdsByDepartmentIds(Lists.newArrayList((Iterable)displayDep));
        }

        boolean finalNeedFilter = filterInfo.isNeedFilterAppAdmin();
        List<DepartmentModel> departmentModelList = new ArrayList();

        Set<String> displayDep2 =     displayDep;
        int departmentTotalSize = 0;
        RelatedCorpSettingModel relatedCorpSettingModel2= relatedCorpSettingModel;;
        if (StringUtils.isBlank(queryType) || "department".equals(queryType)) {
            departmentModelList = this.getOrganizationFacade().searchDepartmentByDepartmentName(name, true);
            departmentTotalSize = ((List)departmentModelList).size();
            if (!CollectionUtils.isEmpty((Collection)departmentModelList)) {
                departmentModelList = departmentModelList.stream().filter((dept) -> {
                    boolean var10000;
                    label22: {
                        boolean nonNull = Objects.nonNull(dept);
                        boolean isTrue = nonNull && managePermChildDepartment.contains(dept.getId());
                        if (finalNeedFilter) {
                            if (!isTrue) {
                                break label22;
                            }
                        } else if (!nonNull) {
                            break label22;
                        }

                        if (dept.getIsShow()) {
                            var10000 = true;
                            return var10000;
                        }
                    }

                    var10000 = false;
                    return var10000;
                }).filter((model) -> {
                    if (finalNeedFilterCorp && !filterCorpIdSet.contains(model.getCorpId())) {
                        return false;
                    } else {
                        return StringUtils.isBlank(deptIds) ? true : displayDep2.contains(model.getId());
                    }
                }).filter((dept) -> {
                    RelatedCorpSettingModel model = (RelatedCorpSettingModel)corpMap.get(dept.getCorpId());
                    return Objects.equals(!Objects.isNull(model) && model.getEnabled(), Boolean.TRUE);
                }).collect(Collectors.toList());

                if (!CollectionUtils.isEmpty((Collection)departmentModelList) && relatedCorpSettingModel != null && relatedCorpSettingModel.getOrgType() == OrgType.RELEVANCE) {
                      //移除根据组织ID查询
//                    departmentModelList = departmentModelList.stream().filter((departmentModel) -> {
//                        return relatedCorpSettingModel2.getCorpId().equals(departmentModel.getCorpId());
//                    }).collect(Collectors.toList());
                }
                String excludedeptid2 =  excludedeptid ;
                if (!CollectionUtils.isEmpty((Collection)departmentModelList) && StringUtils.isNotEmpty(excludedeptid)) {
                    departmentModelList = departmentModelList.stream().filter((it) -> {
                        return !excludedeptid2.equals(it.getId());
                    }).collect(Collectors.toList());
                }

                departmentTotalSize = ((List)departmentModelList).size();
            }

            if (departmentTotalSize > this.organizationUserQuerySize) {
                departmentModelList = ((List)departmentModelList).subList(0, this.organizationUserQuerySize);
            }

            watch.stop();
            log.info("process time1 : {}", watch.getLastTaskTimeMillis());
            watch.start();
        }

        List<DepartmentVO> departmentVOList = null;
        if (!CollectionUtils.isEmpty((Collection)departmentModelList)) {
            List<String> deptIdList = departmentModelList.stream().filter((departmentModel) -> {
                return !departmentModel.getDeleted();
            }).map(BaseModel::getId).collect(Collectors.toList());
            if (departmentTotalSize > 10) {
                deptIdList = (List)deptIdList.stream().filter((item) -> {
                    return !this.idSetCache.contains(item);
                }).collect(Collectors.toList());
            }

            Map<String, List<DepartmentModel>> departmentMap = this.getOrganizationFacade().getDepartmentsByParentIds(deptIdList, true);
            if (StringUtils.isBlank(formRootDeptIds) && StringUtils.equals("portal", sourceType)) {
                departmentModelList = this.selectionHelper.filterDept(currentUser, (List)departmentModelList);
            }

            departmentVOList = departmentModelList.stream().map((departmentModel) -> {
                DepartmentVO departmentVO = new DepartmentVO();
                BeanUtils.copyProperties(departmentModel, departmentVO);
                if (departmentMap != null) {
                    List<DepartmentModel> parentDepartments = (List)departmentMap.get(departmentModel.getId());
                    if (!CollectionUtils.isEmpty(parentDepartments)) {
                        String parentDepartmentName = (String)parentDepartments.stream().sorted(Comparator.comparingInt((o) -> {
                            return -o.getQueryCode().length();
                        })).map(DepartmentModel::getName).collect(Collectors.joining("/"));
                        this.putCache(departmentModel.getId(), parentDepartmentName);
                    }
                }

                departmentVO.setParentDepartmentName((String)this.departmentMapCache.get(departmentModel.getId()));
                return departmentVO;
            }).collect(Collectors.toList());
        }

        watch.stop();
        log.info("process time2 : {}", watch.getLastTaskTimeMillis());
        watch.start();
        Set<String> roleUserIds = null;
        if (StringUtils.isNotBlank(roleIds)) {
            roleUserIds = this.getOrganizationFacade().getUserIdsByRoleIds(Arrays.asList(roleIds.split(",")));
        }

        watch.stop();
        log.info("process time3 : {}", watch.getLastTaskTimeMillis());
        watch.start();
        Set<String> displayUser = new HashSet();
        if (StringUtils.isNotBlank(deptIds) && StringUtils.isNotBlank(roleIds)) {
            displayUser = roleUserIds;
            roleUserIds.retainAll((Collection)depUserIds);
        } else if (StringUtils.isBlank(deptIds) && StringUtils.isNotBlank(roleIds)) {
            displayUser = roleUserIds;
        } else if (StringUtils.isNotBlank(deptIds) && StringUtils.isBlank(roleIds)) {
            displayUser = depUserIds;
        }

        List<UserModel> userModelList = new ArrayList();
        int userTotalSize = 0;
        if (StringUtils.isBlank(queryType) || "user".equals(queryType)) {
            userModelList = this.getOrganizationFacade().searchUsersByName(name, true);
            watch.stop();
            log.info("process time4 : {}", watch.getLastTaskTimeMillis());
            watch.start();
             userTotalSize = ((List)userModelList).size();
            if (!CollectionUtils.isEmpty((Collection)userModelList)) {
                Set<String> permUserIdSet2 =  permUserIdSet;
                Set<String> displayUser2 = displayUser;
                    userModelList = userModelList.stream().filter((userModel) -> {
                    boolean nonNull = Objects.nonNull(userModel);
                    boolean isTrue = nonNull && permUserIdSet2.contains(userModel.getId());
                    return finalNeedFilter ? isTrue : nonNull;
                }).filter((user) -> {
                    if (finalNeedFilterCorp && !filterCorpIdSet.contains(user.getCorpId())) {
                        return false;
                    } else {
                        return StringUtils.isBlank(deptIds) && StringUtils.isBlank(roleIds) ? true : displayUser2.contains(user.getId());
                    }
                }).filter((user) -> {
                    RelatedCorpSettingModel model = (RelatedCorpSettingModel)corpMap.get(user.getCorpId());
                    return Objects.nonNull(model) && Objects.equals(model.getEnabled(), Boolean.TRUE);
                }).collect(Collectors.toList());
                if (!CollectionUtils.isEmpty((Collection)userModelList) && relatedCorpSettingModel != null && relatedCorpSettingModel.getOrgType() == OrgType.RELEVANCE) {
                      //移除根据组织ID查询
//                    userModelList = userModelList.stream().filter((userModel) -> {
//                        return relatedCorpSettingModel2.getCorpId().equals(userModel.getCorpId());
//                    }).collect(Collectors.toList());
                }

                if (!CollectionUtils.isEmpty((Collection)userModelList) && StringUtils.isNotEmpty(workflowInstanceId) && StringUtils.isNotEmpty(activityCode)) {
                    Set<String> participants = this.getWorkflowInstanceFacade().getParticipants(workflowInstanceId, activityCode);
                    if (!CollectionUtils.isEmpty(participants)) {
                        userModelList = userModelList.stream().filter((userModel) -> {
                            return !participants.contains(userModel.getId());
                        }).collect(Collectors.toList());
                    }
                }

                userTotalSize = ((List)userModelList).size();
            }

            if (userTotalSize > this.organizationUserQuerySize) {
                userModelList = ((List)userModelList).subList(0, this.organizationUserQuerySize);
            }
        }

        watch.stop();
        log.info("process time5 : {}", watch.getLastTaskTimeMillis());
        watch.start();
        List<UserSelectionVO> userDetailVOList = null;
        AtomicInteger count = new AtomicInteger(0);
        if (!CollectionUtils.isEmpty((Collection)userModelList)) {
            List<String> deptIdList = userModelList.stream().map(UserModel::getDepartmentId).filter((deptId) -> {
                return !this.idSetCache.contains(deptId);
            }).collect(Collectors.toList());
            List<String> userIdList = userModelList.stream().map(BaseModel::getId).collect(Collectors.toList());
            Map<String, List<DepartmentModel>> departmentMap = this.getOrganizationFacade().getDepartmentsByParentIds(deptIdList);
            watch.stop();
            log.info("process time6 : {}", watch.getLastTaskTimeMillis());
            watch.start();
            List<DepartmentUserModel> departmentUserList = this.getOrganizationFacade().getDepartmentUsersByUserIdsIn(userIdList);
            List<String> allDeptIdList = (List)departmentUserList.stream().map(DepartmentUserModel::getDeptId).collect(Collectors.toList());
            Map<String, DepartmentModel> totalDepartmentMap = (Map)this.getOrganizationFacade().getDepartmentsByDeptIds(allDeptIdList).stream().collect(Collectors.toMap(BaseModel::getId, Function.identity()));
            watch.stop();
            log.info("process time7 : {}", watch.getLastTaskTimeMillis());
            watch.start();
            Map<String, List<RoleModel>> userRoleMap = this.getOrganizationFacade().getRolesByUserIds(userIdList);
            watch.stop();
            log.info("process time8 : {}", watch.getLastTaskTimeMillis());
            watch.start();
            Map<String, List<DepartmentUserModel>> departmentUserMap = (Map)departmentUserList.stream().collect(Collectors.groupingBy(DepartmentUserModel::getUserId));
            List<String> totalIdList = new ArrayList(userIdList);
            totalIdList.addAll((Collection)(userModelList).stream().map(UserModel::getManagerId).collect(Collectors.toList()));
            totalIdList.addAll((Collection)(userModelList).stream().map(UserModel::getSecretaryId).collect(Collectors.toList()));
            totalIdList = (List)totalIdList.stream().distinct().collect(Collectors.toList());
            Map<String, UserModel> userMap = this.getOrganizationFacade().getUsers(totalIdList);
            List<UserUnionExtAttrModel> userUnionExtAttrModelList = this.getEngineService().getUserExtendFacade().getUnionExtAttrsByUserIdList(userIdList);
            Map<String, List<UserUnionExtAttrModel>> extAttrMap = (Map)userUnionExtAttrModelList.stream().collect(Collectors.groupingBy(UserUnionExtAttrModel::getUserId));
            watch.stop();
            log.info("process time9 : {}", watch.getLastTaskTimeMillis());
            watch.start();
            userDetailVOList = userModelList.stream().map((userModel) -> {
                UserSelectionVO userSelectionVO = new UserSelectionVO();
                BeanUtils.copyProperties(userModel, userSelectionVO);
                List<DepartmentModel> deptUsers;
                if (departmentMap != null) {
                    deptUsers = (List<DepartmentModel>)departmentMap.get(userModel.getDepartmentId());
                    if (!CollectionUtils.isEmpty(deptUsers)) {
                        String parentDepartmentName = deptUsers.stream().sorted(Comparator.comparingInt((o) -> {
                            return -o.getQueryCode().length();
                        })).map(DepartmentModel::getName).collect(Collectors.joining("/"));
                        this.putCache(userModel.getDepartmentId(), parentDepartmentName);
                    }
                }

                userSelectionVO.setParentDepartmentName((String)this.departmentMapCache.get(userModel.getDepartmentId()));
                deptUsers = (List)departmentUserMap.get(userModel.getId());
//                if (CollectionUtils.isEmpty(deptUsers)) {
//                    deptUsers = this.getOrganizationFacade().getDepartmentUsersByUserId(userModel.getId());
//                    count.incrementAndGet();
//                }

                List<SelectionValue> valueList = Lists.newArrayListWithCapacity(deptUsers.size());
                Iterator var12 = deptUsers.iterator();

                while(var12.hasNext()) {
                    DepartmentUserModel deptUser = (DepartmentUserModel)var12.next();
                    DepartmentModel department = (DepartmentModel)totalDepartmentMap.get(deptUser.getDeptId());
                    if (!totalDepartmentMap.containsKey(deptUser.getDeptId())) {
                        department = this.getOrganizationFacade().getDepartment(deptUser.getDeptId());
                        count.incrementAndGet();
                    }

                    if (!Objects.isNull(department) && department.getIsShow() && department.getEnabled()) {
                        String departName = (String)Optional.of(department).map(DepartmentModel::getName).orElse(null);
                        String departId = (String)Optional.of(department).map(BaseModel::getId).orElse(null);
                        SelectionValue selectionValue = new SelectionValue();
                        selectionValue.setId(departId);
                        selectionValue.setName(departName);
                        selectionValue.setType(UnitType.DEPARTMENT);
                        valueList.add(selectionValue);
                    }
                }

                userSelectionVO.setDepartments(valueList);
                List<RoleModel> roleModelList = (List)userRoleMap.get(userModel.getId());
                List<UserUnionExtAttrModel>userUnionList;
                if (!CollectionUtils.isEmpty(roleModelList)) {
                    List<String> roleNameList = (List)roleModelList.stream().filter(Objects::nonNull).map(RoleModel::getName).collect(Collectors.toList());
                    userUnionList = (List)roleModelList.stream().filter(Objects::nonNull).map(BaseModel::getId).collect(Collectors.toList());
                    if (!roleNameList.isEmpty()) {
                        userSelectionVO.setRoleName(String.join(",", roleNameList));
                        userSelectionVO.setRoleIds(roleNameList);
                    }
                }

                this.setManagerAndSecretary(userModel, userSelectionVO, userMap, count);
                Map<String, Object> propertiesMap = new HashMap();
                userUnionList = extAttrMap.get(userModel.getId());
                if (CollectionUtils.isNotEmpty(userUnionList)) {
                    userUnionList.forEach((userUnion) -> {
                        UserExtAttrModel userExtAttrModel = this.getEngineService().getUserExtendFacade().getUserExtendByExtendAttrId(userUnion.getExtendAttrId());
                        if (userExtAttrModel != null) {
                            propertiesMap.put(userExtAttrModel.getCode(), userUnion.getMapVal());
                        }

                    });
                }

                Object obj = ReflectUtil.getObject(userSelectionVO, propertiesMap);
                return (UserSelectionVO)obj;
            }).collect(Collectors.toList());
        }

        watch.stop();
        log.info("process time10 : {}", watch.getLastTaskTimeMillis());
        watch.start();
        if (StringUtils.isBlank(formRootDeptIds) && StringUtils.equals("portal", sourceType)) {
            userDetailVOList = this.selectionHelper.filterUser(currentUser, userDetailVOList);
        }

        int deptSize = CollectionUtils.isEmpty(departmentVOList) ? 0 : departmentVOList.size();
        int userSize = CollectionUtils.isEmpty(userDetailVOList) ? 0 : userDetailVOList.size();
        watch.stop();
        log.info("process time9 : {}", watch.getLastTaskTimeMillis());
        log.info("process time total : {}", watch.getTotalTimeMillis());
        return this.getOkResponseResult(new DepartmentUserTreeVO(departmentVOList, deptSize, userDetailVOList, userSize), "查询用户信息成功");
    }


    private Set<String> getLoginUserDeptPermAndSelectUsersMixed(Set<String> allPathDeptSet, String selectUserIds) {
        if (StringUtils.isBlank(selectUserIds)) {
            return null;
        } else {
            String[] split = selectUserIds.split(",");
            List<DepartmentUserModel> departmentUserModels = new ArrayList();
            String[] var5 = split;
            int var6 = split.length;

            for(int var7 = 0; var7 < var6; ++var7) {
                String userId = var5[var7];
                departmentUserModels.addAll(this.getOrganizationFacade().getDepartmentUsersByUserId(userId));
            }

            List<String> collect = (List)departmentUserModels.stream().map((departmentUserModel) -> {
                return departmentUserModel.getDeptId();
            }).collect(Collectors.toList());
            Set<String> deptChildIdSet = (Set)this.getOrganizationFacade().getDepartmentsChildList(collect, false).stream().map(BaseModel::getId).collect(Collectors.toSet());
            deptChildIdSet.retainAll(allPathDeptSet);
            return deptChildIdSet;
        }
    }

    private void setManagerAndSecretary(UserModel user, UserSelectionVO userSelectionVO, Map<String, UserModel> userMap, AtomicInteger count) {
        String managerId = user.getManagerId();
        String userId;
        String userName;
        if (!StringUtils.isBlank(managerId)) {
            UserModel manager = (UserModel)userMap.get(managerId);
            if (!userMap.containsKey(managerId)) {
                manager = this.getOrganizationFacade().getUser(managerId);
                count.incrementAndGet();
            }

            userId = (String)Optional.ofNullable(manager).map(BaseModel::getId).orElse(null);
            userName = (String)Optional.ofNullable(manager).map(UserModel::getName).orElse(null);
            if (manager != null) {
                SelectionValue selectionValue = new SelectionValue();
                selectionValue.setType(UnitType.USER);
                selectionValue.setName(userId);
                selectionValue.setId(userId);
                selectionValue.setImgUrl(userName);
                userSelectionVO.setManagerSelection(selectionValue);
                userMap.put(managerId, manager);
            }
        }

        String secretaryId = user.getSecretaryId();
        if (!StringUtils.isBlank(secretaryId)) {
            UserModel secretary = (UserModel)userMap.get(secretaryId);
            if (!userMap.containsKey(secretaryId)) {
                secretary = this.getOrganizationFacade().getUser(secretaryId);
                count.incrementAndGet();
            }

            userId = (String)Optional.ofNullable(secretary).map(BaseModel::getId).orElse(null);
            userName = (String)Optional.ofNullable(secretary).map(UserModel::getName).orElse(null);
            String imgUrl = (String)Optional.ofNullable(secretary).map(UserModel::getImgUrl).orElse(null);
            if (secretary != null) {
                SelectionValue selectionValue = new SelectionValue();
                selectionValue.setType(UnitType.USER);
                selectionValue.setName(userName);
                selectionValue.setId(userId);
                selectionValue.setImgUrl(imgUrl);
                userSelectionVO.setSecretary(selectionValue);
                userMap.put(secretaryId, secretary);
            }
        }

    }



    private synchronized void putCache(String id, String parentDepartmentName) {
        if (!this.idSetCache.contains(id)) {
            this.idSetCache.add(id);
            this.departmentMapCache.put(id, parentDepartmentName);
        }
    }

}
